#ifndef _MY_UTIL_
#define _MY_UTIL_
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<sys/stat.h>
#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
#include <experimental/filesystem>

namespace cloud {
    namespace fs = std::experimental::filesystem;
    class FileUtil {//文件实用类工具设计
    private:
        std::string _filename;
    public:
        FileUtil(const std::string& filename) :_filename(filename) {}//构造函数
        int64_t FileSize() {
            struct stat st;//获取文件信息接口
            if (stat(_filename.c_str(), &st) < 0) {
                return -1;
                std::cout << "Get file_size failed\n";
                return -1;
            }
            return st.st_size;//返回文件大小

        }//获取文件大小
        time_t LastTime() {
            struct stat st;//获取文件信息接口
            if (stat(_filename.c_str(), &st) < 0) {
                return -1;
                std::cout << "Get file_size failed\n";
                return -1;
            }
            return st.st_mtime;

        }//文件最后一次修改时间
        time_t LastATime() {
            struct stat st;//获取文件信息接口
            if (stat(_filename.c_str(), &st) < 0) {
                return -1;
                std::cout << "Get file_size failed\n";
                return -1;
            }
            return st.st_atime;

        }//文件最后一次访问时间
        std::string FileName() {
            // ./abc/test.tst
            size_t pos = _filename.find_last_of("\\");//找到路径的最后一个斜杠
            if (pos == std::string::npos) {//本身就是文件名
                return _filename;
            }
            //fs::path(_filename)
            return _filename.substr(pos + 1);
        }//文件名称获取
        bool GetPosLen(std::string* body, size_t pos, size_t len) {//获取指定长度的数据
            std::ifstream ifs;
            ifs.open(_filename, std::ios::binary);//二进制打开文件
            if (ifs.is_open() == false) {
                std::cout << "open file failed?\n";
                return false;
            }
            size_t fsize = this->FileSize();//获取当前文件大小
            if (pos + len > fsize) {//超出文件大小 
                std::cout << " get file len is erron\n";
                return false;
            }

            ifs.seekg(pos, std::ios::beg);
            body->resize(len);
            ifs.read(&(*body)[0], len);//读取文件 
            if (ifs.good() == false) {
                std::cout << "get file content failed\n";
                ifs.close();
                return false;
            }
            ifs.close();
            return true;
        }
        bool GetContent(std::string* body) {//获取文件全部内容
            size_t fsize = this->FileSize();//获取当前文件大小
            return GetPosLen(body, 0, fsize);
        }
        bool SetContent(const std::string& body) {//写入文件数据
            std::ofstream ofs;
            ofs.open(_filename, std::ios::binary);
            if (ofs.is_open() == false) {
                std::cout << "write open failed.\n";
                return false;
            }
            ofs.write(&body[0], body.size());//写入数据
            if (ofs.good() == false) {
                std::cout << "write file content failed!\n";
                ofs.close();
                return false;
            }
            ofs.close();
            return true;
        }

        bool Exists() {//判断文件是否存在
            return fs::exists(_filename);
        }
        bool CreateDirectory() {//创建目录
            if (this->Exists()) return true;
            return fs::create_directories(_filename);
        }
        bool ScanDirectory(std::vector<std::string>* arry) {//列出这个目录下的文件
            this->CreateDirectory();
            for (auto& p : fs::directory_iterator(_filename)) {
                if (fs::is_directory(p) == true) {//如果是目录
                    continue;
                }
                //relative_path 带有路劲的文件名
                arry->push_back(fs::path(p).relative_path().string());
            }
            return true;
        }
    };

    

}
#endif